package com.qf.mybatisplus.utils;


import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
//import com.lowagie.text.pdf.BarcodePDF417;

import com.itextpdf.text.pdf.BarcodePDF417;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: hzmoko
 * @description: 二维码工具
 * @author: code
 * @create: 2018-12-15 15:00
 * @since: jdk1.8
 **/
public class EwmUtils {

    public static final Logger logger = LoggerFactory.getLogger(EwmUtils.class);

    // logo默认边框颜色
    public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;
    // logo默认边框宽度
    public static final int DEFAULT_BORDER = 1;
    // logo大小默认为照片的1/6
    public static final int DEFAULT_LOGOPART = 4;

    public final int border = DEFAULT_BORDER;
    //自定义颜色
    public final Color borderColor;
    // 自定义logo大小
    public final int logoPart;

    /**
     * 颜色上创建一个默认配置,生成正常的黑白条码。
     */
    public EwmUtils() {
        this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
    }

    public EwmUtils(Color borderColor, int logoPart) {
        this.borderColor = borderColor;
        this.logoPart = logoPart;
    }

    public Color getBorderColor() {
        return borderColor;
    }

    public int getBorder() {
        return border;
    }

    public int getLogoPart() {
        return logoPart;
    }

    /**
     * 给二维码图片添加Logo
     *
     * @param qrPic   二维码文件
     * @param logoPic logo文件
     */
    public static void addLogo_QRCode(File qrPic, File logoPic, EwmUtils creatrQrCode) {
        try {
            if (!qrPic.isFile() || !logoPic.isFile()) {

                return;
            }
            //读取二维码图片，并构建绘图对象
            BufferedImage image = ImageIO.read(qrPic);
            Graphics2D g = image.createGraphics();
            //读取Logo图片
            BufferedImage logo = ImageIO.read(logoPic);
            //保持二维码是正方形的
            int widthLogo = image.getWidth() / creatrQrCode.getLogoPart();
            int heightLogo = image.getWidth() / creatrQrCode.getLogoPart();
            // 计算图片放置位置
            int x = (image.getWidth() - widthLogo) / 2;
            int y = (image.getHeight() - heightLogo) / 2;
            //开始绘制图片
            g.drawImage(logo, x, y, widthLogo, heightLogo, null);
            g.drawRoundRect(x, y, widthLogo, heightLogo, 10, 10);
            g.setStroke(new BasicStroke(creatrQrCode.getBorder()));
            g.setColor(creatrQrCode.getBorderColor());
            g.drawRect(x, y, widthLogo, heightLogo);
            g.dispose();
            ImageIO.write(image, "jpeg", qrPic);
        } catch (Exception e) {

        }
    }

    /**
     * 二维码图片添加文字
     *
     * @param pressText 文字
     * @param newImg    带文字的图片
     * @param targetImg 需要添加文字的图片
     * @param fontStyle 文字样式
     * @param color     颜色
     * @param fontSize  字体大小
     * @param width     图片宽度
     * @param height    图片高度
     */
    public static void pressText(String pressText, String newImg, String targetImg, int fontStyle, Color color, int fontSize, int width, int height) {

        //计算文字开始的位置
        //x开始的位置：（图片宽度-字体大小*字的个数）/2
        int startX = (width - (fontSize * pressText.length())) / 300;
        //y开始的位置：图片高度-（图片高度-图片宽度）/2
        int startY = height - (height - width) / 3;
        try {
            File file = new File(targetImg);
            Image src = ImageIO.read(file);
            int imageW = src.getWidth(null);
            int imageH = src.getHeight(null);
            BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.createGraphics();
            g.drawImage(src, 0, 0, imageW, imageH, null);
            g.setColor(color);
            g.setFont(new Font(null, fontStyle, fontSize));
            g.drawString(pressText, startX, startY);
            g.dispose();
            String formatName = newImg.substring(newImg.lastIndexOf(".") + 1);
            ImageIO.write(image, formatName, new File(newImg));

//            FileOutputStream out = new FileOutputStream(newImg);
//            ImageIO.write(image, "JPEG", out);
//            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//            encoder.encode(image);
//            out.close();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    /**
     * 生成二维码（无logo，无文字）
     *
     * @param qrcPath 用来存放生成的二维码图片
     * @param content 二维码表示的内容
     */
    public static String createQrCode(String qrcPath, String content) {
        int width = 250;
        int height = 250;
        String image = null;
        try {
            File qrcFile = new File(qrcPath);
            if (!qrcFile.exists()) {
                qrcFile.mkdirs();
            }
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            Map hints = new HashMap();
            //设置UTF-8， 防止中文乱码
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            //设置二维码四周白色区域的大小
            hints.put(EncodeHintType.MARGIN, 0);
            //设置二维码的容错性
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            //画二维码，记得调用multiFormatWriter.encode()时最后要带上hints参数，不然上面设置无效
            BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            //开始画二维码
            MatrixToImageWriter.writeToFile(bitMatrix, "png", qrcFile);
            //转换成base64

            image = Base64Util.imageToBase64(qrcPath);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return image;
    }

    /**
     * 保定生成条形码
     *
     * @param qrcPath
     * @param slid
     * @return
     */
    public static String createBdQrCode(String qrcPath, String slid) {
        String image = null;
        try {
            BarcodePDF417 pdf = new BarcodePDF417();
            pdf.setText(slid.getBytes("GBK"));
            Image pdfImg = pdf.createAwtImage(Color.black, Color.white);
            BufferedImage img = new BufferedImage(pdfImg.getWidth(null), pdfImg.getHeight(null), 1);
            Graphics g = img.getGraphics();
            g.drawImage(pdfImg, 0, 0, Color.white, null);
            File folder = new File(qrcPath);
            if (!folder.exists()) {
                folder.mkdirs();
            }
            String filePath = qrcPath + "/qrcode.jpg";
            File ewmFile = new File(filePath);
            FileOutputStream os = new FileOutputStream(ewmFile);
            ImageIO.write(img, "PNG", os);
            os.close();
            image = Base64Util.imageToBase64(filePath);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return image;

    }

    public static String noWriterEwm(String path, String ewm) throws WriterException, IOException {
        if (ewm == null || "".equals(ewm)) {
            ewm = "      ";
        }
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();

        hints.put(EncodeHintType.MARGIN, 0);

        BitMatrix bitMatrix = new QRCodeWriter().encode(ewm,
                BarcodeFormat.QR_CODE, 256, 256, hints);
        //1.1去白边
        int[] rec = bitMatrix.getEnclosingRectangle();
        int resWidth = rec[2] + 1;
        int resHeight = rec[3] + 1;
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
        resMatrix.clear();
        for (int i = 0; i < resWidth; i++) {
            for (int j = 0; j < resHeight; j++) {
                if (bitMatrix.get(i + rec[0], j + rec[1])) {
                    resMatrix.set(i, j);
                }
            }
        }
        //2
        int width = resMatrix.getWidth();
        int height = resMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, resMatrix.get(x, y) == true ? Color.BLACK.getRGB() : Color.WHITE.getRGB());
            }
        }
        //3
        File file = new File(path);
        File parent = file.getParentFile();
        //如果pdf保存路径不存在，则创建路径
        if (!parent.exists()) {
            parent.mkdirs();
        }
        ImageIO.write(image, "png", file);
        return Base64Util.imageToBase64(path);
    }

    /**
     * 生成二维码（有logo，无文字）
     *
     * @param qrcPath  用来存放生成的二维码图片
     * @param content  二维码表示的内容
     * @param width    图片完整的宽
     * @param height   图片完整的高
     * @param logoPath 附加在二维码中的图片
     */
    public void createLogoQrCode(String qrcPath, String content, int width, int height, String logoPath) {
        //准备一张二维码
        createQrCode(qrcPath, content);
        //在二维码中加入图片
        EwmUtils creatrQrCode = new EwmUtils();
        File logoFile = new File(logoPath);
        File qrcFile = new File(qrcPath);
        addLogo_QRCode(qrcFile, logoFile, creatrQrCode);
    }

    /**
     * 生成二维码（无logo，有文字）
     *
     * @param newImageWithText 用来存放的带有文字的二维码图片
     * @param targetImage      原二维码图片
     * @param text             附加在图片上的文字信息
     * @param width            图片宽度（用来计算文字x开始位置）
     * @param height           图片高度（用来计算文字y开始位置）
     */
    public void createWordQrcode(String newImageWithText, String targetImage, String text, int width, int height) {
        //准备一张二维码
        createQrCode(newImageWithText, text);
        //字体大小
        int font = 20;
        //字体风格
        int fontStyle = 4;
        //在二维码下方添加文字（是否替换原图）
        if (org.apache.commons.lang.StringUtils.isNotBlank(targetImage)) {
            pressText(text, newImageWithText, targetImage, fontStyle, Color.red, font, width, height);
        } else {
            pressText(text, newImageWithText, newImageWithText, fontStyle, Color.red, font, width, height);
        }
    }

    /**
     * 生成二维码（有logo，有文字）
     *
     * @param newImageWithText 用来存放的带有文字的二维码图片
     * @param targetImage      原二维码图片
     * @param text             附加在二维码上的文字信息
     * @param width            图片宽度（用来计算文字x开始位置）
     * @param height           图片高度（用来计算文字y开始位置）
     * @param logoPath         附加在二维码上的图片
     */
    public void createWordLogoQrcode(String newImageWithText, String targetImage, String text, int width, int height, String logoPath) {
        //准备一张二维码
        createLogoQrCode(newImageWithText, text, width, height, logoPath);
        //字体大小
        int font = 20;
        //字体风格
        int fontStyle = 4;
        //在二维码下方添加文字（是否替换原图）
        if (org.apache.commons.lang.StringUtils.isNotBlank(targetImage)) {
            pressText(text, newImageWithText, targetImage, fontStyle, Color.red, font, width, height);
        } else {
            pressText(text, newImageWithText, newImageWithText, fontStyle, Color.red, font, width, height);
        }
    }

    /**
     * @discription 生成二维base64,无需生成文件
     * @author Cola.Niu
     * @param content
     * @return
     */
    public static String createQrCode(String content){
        try {
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
//            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 250, 250);
            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, 250, 250, hints);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);

            Base64.Encoder encoder = Base64.getEncoder();

            return encoder.encodeToString(outputStream.toByteArray());
        } catch (WriterException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }


    public static void main(String args[]) {
        try {
            String qrCode1 = createQrCode("/Users/wangyangrui/Documents/废弃备份文件/picture1", "80F52304DCB5D375F4F93BDE2EEAC07A8FB856804519CDFD1851715F66DD0B7E158A0239B444BCE207FF54E49B54C7A13D7A95AB215281E96CAAA479FCEB2C0C2A8E041E3FA7BF271982FD34DECCBB3382FA03229D9C795C0B91AF557A044BC1901748D02510EDC54CD3DEABD42D461D859DDB41446280DE825C7D5E91DFB5D803B091D4D4DF5A09AFECCDAD5E0D4FC2C8E44EE0BBA3844A512A337E97BB689BA30A01C699F912797386EF7AA6CA802734D642DDCEFEEFEC257D50752A67D28278DDF5BE02A4DF080DC1D8591227C8F62192CDDFABE66ACE1041BC01D1B6826B7F07572B34348369B146D8406610E752A10A8A79EB4C3BD13E9B537FA3D1B66DCD5891664CA534C208F820629FA9116215C40E73F9C7707F1AD2A9075BCC42FF2481A05536DB72E9E2822243A42ED1B3BAA776C4BD8DC955C93D6A46AE0A0DAA243AA313884166BB4BD76409488E6D25876500F8FE79F5FCBA2D01736728E32FCE97CEACB8AE752634F722C683475A524625A977B5DDD2F7946984105BFEF8029F720DA8A63E3F03A59169CE1EBDA3C687A3EBAB47090666DE1D7B4A033DF5A6DD3CC9D91E00EB594CAFF145121EE22D8CD3BDB52A8827E7EECF9D6D361481235BE681E761667042ED651993C9F9E698DE82534CABEAB0A8FD804119248A05678D7050AA7DD7EA0CD8E00D59EED8801C78847EAB");


            String qrCode3 = noWriterEwm("/Users/wangyangrui/Documents/废弃备份文件/picture3", "F608DC7FABD0E4BFF58B0EBF1A0A41AA59AA4A80B38C7E957BE547684E63DBD0CE454C8CDF78A56A5D760A0C19E31A720265258C71250EC46850D24AEBFF0171F7B1F0AF761A03D0B0CEE5C35E9C65BE210AF5E2CE0BD5150393F19C1E98970D4163480B69109E01DF145D649358EAA9EE3170C119186788DA36356A488B177E7A57FFBE97630B3F21EB39128411DFD9596A4D2F91AF6E8A6CCF8214F4A73B1036904DCB1A99A74C0BE0FCCB928A893DFBE33B4581E6914602BA9604F6F1DF12947608206DAC3D00229061872098B1F4256FAA1E261A65830DF26900A9FCC152AC2F74718BA1F3757C779439A0CB9BEDEE8DE0FBACEC7A9B435A92ECFCB5437A21B7719A0D329E2B5C63D1E96CCD401D0649070B2991E70FFFF7548BCE2CB78098A23D802CCC91BB969D5500D3ADDECCF11C57D3DF817F14998D78681FE53788D4418F346D203410248C92B336F0CED93E8DCBFA05316303DCDBA4BFAF93262F56D37682695883F54DB0DADFC7B7DC042A56F8F60594BFC022F09A0133B557B35C171530BD2C921E2C1131C229E236F5C0EC386C8055D80CD77E095364EF2AA060487C10EC0D24586196DA116C6211328F785758AFFE3970E462F557C036425504FB93FB3176B67EF0F9266AB597793DFABBCB92A3306749D2897F053299067FBBB3607964E8F5406568B1E54B6652F91FEF130DDCE824B413543A8E7B9100590D03D063CD1399085754C5A7B711733AFBDE0F7E5A087971CC873CD9BCE728D5DBED29ED523758F5F608DC7FABD0E4BFF58B0EBF1A0A41AA59AA4A80B38C7E957BE547684E63DBD0CE454C8CDF78A56A5D760A0C19E31A720265258C71250EC46850D24AEBFF0171F7B1F0AF761A03D0B0CEE5C35E9C65BE210AF5E2CE0BD5150393F19C1E98970D4163480B69109E01DF145D649358EAA9EE3170C119186788DA36356A488B177E7A57FFBE97630B3F21EB39128411DFD9596A4D2F91AF6E8A6CCF8214F4A73B1036904DCB1A99A74C0BE0FCCB928A893DFBE33B4581E6914602BA9604F6F1DF12947608206DAC3D00229061872098B1F4256FAA1E261A65830DF26900A9FCC152AC2F74718BA1F3757C779439A0CB9BEDEE8DE0FBACEC7A9B435A92ECFCB5437A21B7719A0D329E2B5C63D1E96CCD401D0649070B2991E70FFFF7548BCE2CB78098A23D802CCC91BB969D5500D3ADDECCF11C57D3DF817F14998D78681FE53788D4418F346D203410248C92B336F0CED93E8DCBFA05316303DCDBA4BFAF93262F56D37682695883F54DB0DADFC7B7DC042A56F8F60594BFC022F09A0133B557B35C171530BD2C921E2C1131C229E236F5C0EC386C8055D80CD77E095364EF2AA060487C10EC0D24586196DA116C6211328F785758AFFE3970E462F557C036425504FB93FB3176B67EF0F9266AB597793DFABBCB92A3306749D2897F053299067FBBB3607964E8F5406568B1E54B6652F91FEF130DDCE824B413543A8E7B9100590D03D063CD1399085754C5A7B711733AFBDE0F7E5A087971CC873CD9BCE728D5DBED29ED523758F5");


            System.out.println(qrCode1);
            System.out.println(qrCode3);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

